/******************************************************************************
 * Copyright (C) 2017 Chengdu Dlhd information industry co. LTD.
 * All Rights Reserved.
 * 本软件为成都顶联互动信息产业有限公司开发研制。未经本公司正式书面同意，其他任何个人、团体不得使用、复制、修改或发布本软件.
 *****************************************************************************/
package net.dgg.dggcloud.service.iboss.service.sc;

import net.dgg.dggcloud.core.json.JsonUtil;
import net.dgg.dggcloud.core.minidao.hibernate.dao.IGenericBaseCommonDao;
import net.dgg.dggcloud.core.util.NJCodeUtil;
import net.dgg.dggcloud.core.util.StringUtils;
import net.dgg.dggcloud.service.common.exception.BizException;
import net.dgg.dggcloud.service.entity.user.User;
import net.dgg.dggcloud.service.iboss.constant.OverdueStateConstant;
import net.dgg.dggcloud.service.iboss.dao.sc.OrderInfoDao;
import net.dgg.dggcloud.service.iboss.entity.ScProOrderTimeState;
import net.dgg.dggcloud.service.jrcrm.entity.customer.Customer;
import net.dgg.dggcloud.service.jrcrm.entity.orf.OrderContact;
import net.dgg.dggcloud.service.jrcrm.service.customer.api.CustomerApiService;
import net.dgg.dggcloud.service.jrcrm.service.orf.OrderContactService;
import net.dgg.dggcloud.service.jrcrm.utils.TranslateMapUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import net.dgg.dggcloud.service.iboss.utils.Property;
import net.dgg.dggcloud.service.iboss.entity.ScOrder;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @author 赵有文
 * @description 生产订单信息service层
 * @date 2017/11/28
 */
@Service
@SuppressWarnings("unused")
public class OrderInfoService {
    @Autowired
    private NJCodeUtil njCodeUtil;
    @Resource(name = "miniDaoHiberCommonDao")
    protected IGenericBaseCommonDao repository;
    @Autowired
    private CustomerApiService customerService;
    @Autowired
    private NodeManagerService nodeManagerService;
    @Autowired
    private OrderContactService orderContactService;
    @Autowired
    private CustomerApiService customerApiService;
    @Autowired
    private OrderInfoDao orderInfoDao;
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    private static String[] column = new String[]{"btcode", "status"};//需要翻译的列

    /**
     * 查询单个生产订单信息
     *
     * @param map 生产订单id 或 生产订单编号
     * @return 生产订单信息Map
     */
    public Map querySingleOrderByMap(Map map) {
        if (map.get("orderId") == null && map.get("orderBusinessNo") == null) return null;
        List<Map> orderList = orderInfoDao.queryOrderListByMap(map);
        if (orderList != null && orderList.size() > 0) {
            generateBusiTypeMark(orderList);

            //查询订单预计完成时间
            Map order = orderList.get(0);
            order.put("statusCode", order.get("status"));

            ScProOrderTimeState orderTimeState = repository.get(ScProOrderTimeState.class, Long.valueOf(order.get("id").toString()));
            if (orderTimeState != null) {
                order.put("expectedFinishDate", orderTimeState.getOrderOverdueTime());
            }
            translateOrderPrice(order, TranslateType.forWebShow);
            //解密客户电话号码
            Object value = order.get("customerPhone");
            if (value != null && value.toString().length() > 0) {
                order.put("customerPhone",njCodeUtil.decrypt(value.toString()));
            }

            TranslateMapUtil.translateMap(column, orderList);

            generateOrderFlowList(order);
            associateQurySalesOrderInfo(order);
            trimOrderInfo(order);
            return order;
        }
        return null;
    }


    /**
     * 查询客户相关联的所有(子)生产订单
     *
     * @param map 参数列表,仅需要客户id
     * @return
     */
    public List<Map> queryRelatedOrderByMap(Map map) {
        List<Map> orderList = orderInfoDao.queryRelatedOrderByMap(map);
        if (orderList != null) {
            TranslateMapUtil.translateMap(column, orderList);
        }
        return orderList;
    }

    /**
     * 查询订单的废单，退单有关操作记录
     *
     * @param map 参数列表,仅需要生产订单id
     * @return
     */
    public List<Map> queryNegativeOperationRecordByMap(Map map) {
        return orderInfoDao.queryNegativeOperationRecordByMap(map);
    }

    /**
     * 查询客户属性
     *
     * @param customerId
     * @return
     */
    public Customer queryCustomerById(long customerId) {
        return customerService.getCustomerById(customerId);


    }


    /**
     * 根据业态详细编码，生成业态类型识别码 如： BUS_YT_XYDK_2 提取成 XYDK
     *
     * @param order 单个订单
     */
    private void generateBusiTypeMark(Map order) {
        String code = "";
        if (order.get("btCode") != null) {
            code = order.get("btCode").toString();
        }
        Pattern p = Pattern.compile("(DYDK|XYDK|ZJYW)");
        Matcher m = p.matcher(code);
        if (m.find()) {
            order.put("BusiTypeMark", m.group(0));
        }
    }

    /**
     * 根据业态详细编码，生成业态类型识别码 如： BUS_YT_XYDK_2 提取成 XYDK
     *
     * @param orderList 订单集合
     */
    private void generateBusiTypeMark(List<Map> orderList) {
        for (Map order : orderList) {
            generateBusiTypeMark(order);
        }
    }

    /**
     * @param map 参数
     * @auther 黄兴贵
     * 更新借贷人相关(订单详情)
     * 涉及更新内容：生产子订单信息(sc_product_order)、客户信息(cus_customer)、客户关系表（orderContact）
     */
    public void updateLenders(Map<String, Object> map) {
        try {
            String loaninfos = map.get("loaninfos") == null ? "" : map.get("loaninfos").toString();
            Long scProductId = Long.parseLong(String.valueOf(map.get("scProductId")));
            if (StringUtils.isNotEmpty(loaninfos)) {
                List<OrderContact> orderContacts = JsonUtil.json2List(loaninfos.toString(), OrderContact.class);
//                Long orderId = (Long) map.get("orderId");
                User user = (User) map.get("user");
                if (null != orderContacts && !orderContacts.isEmpty()) {
                    for (OrderContact orderContact : orderContacts) {
                        if (orderContact.getId() != null) {
                            OrderContact oldOrderContact = orderContactService.getByIdHiber(orderContact.getId());
                            if (oldOrderContact != null) {
                                oldOrderContact.setName(orderContact.getName());
                                oldOrderContact.setCardId(orderContact.getCardId());
                                //加密电话号码
                                String phone=njCodeUtil.encrypt(orderContact.getNo());
                                oldOrderContact.setNo(phone);
                                oldOrderContact.setRelationshipOfCus(orderContact.getRelationshipOfCus());
                                oldOrderContact.setChildrenNum(orderContact.getChildrenNum());
                                oldOrderContact.setMaritalStatus(orderContact.getMaritalStatus());
                                oldOrderContact.setNoKnow(orderContact.getNoKnow());
                                oldOrderContact.setIsSelf(orderContact.getIsSelf());
                            }
                            //更新客户关系表
                            orderContactService.updateOrderContact(oldOrderContact, user);
                        } else {
                            throw new RuntimeException();
                        }

                        //判断是否客户本人
                        if (orderContact.getIsSelf() != null && orderContact.getIsSelf() == 1) {
                            //

                            //客户本人
                            // 更新生产子订单
                            Map<String, Object> orderInforMap = new HashMap<>();
                            orderInforMap.put("orderId", scProductId);
                            //查询订单详情
                            Map scOrder = querySingleOrderByMap(orderInforMap);
                            orderInforMap.remove("orderId");
                            orderInforMap.put("customerName", orderContact.getName());
                            //
                            // 密码明文
                            orderInforMap.put("customerPhoneBak", orderContact.getNo());
                            // 密码暗文
                            orderInforMap.put("customerPhone", njCodeUtil.encrypt(orderContact.getNo()));
                            orderInforMap.put("flowUserName", scOrder.get("flowusername"));
                            orderInforMap.put("id", scProductId);
//                            updateOrderInfoByMap(orderInforMap,true);
                            updateOrderInfoByMap(orderInforMap);

                            //更新生产主订单
                            String encryptPhone=njCodeUtil.encrypt(orderContact.getNo());
                            Long scId=Long.valueOf(scOrder.get("proOrderId").toString());
                            ScOrder scMainOrder=this.repository.get(ScOrder.class,scId);
                            scMainOrder.setContactPhone(encryptPhone);

                            //更新客户信息
                            map.put("id", scOrder.get("customerid"));
                            map.put("businessId", scOrder.get("businessid"));
                            map.put("User", user);
                            map.put("idCard", orderContact.getCardId());
                            map.put("customerPhone", orderContact.getNo());
                            map.put("name", orderContact.getName());
                            customerApiService.updateCustomer(map);
                            //
                            Map para = new HashMap();

                            para.put("customerId", scOrder.get("customerid"));
                            para.put("customerName", orderContact.getName());
                            para.put("customerPhone", njCodeUtil.encrypt(orderContact.getNo()));

                            para.put("flowUserName", scOrder.get("flowusername"));
                            if (para.get("customerId") != null && !para.get("customerId").toString().trim().equals("")) {
                                orderInfoDao.updateOrderInfoByMap(para);
                            } else {
                                throw new BizException("保存订单联系人异常:", 10006);
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new BizException("保存订单联系人异常:" + e.getMessage(), 10006);
        }
    }

    /**
     * 更新生产订单信息
     *
     * @param orderInfoMap 订单更新字段集合
     * @param ignoreEmpty  是否忽略空值字段
     */
    public void updateOrderInfoByMap(Map orderInfoMap, boolean ignoreEmpty) {
        if (ignoreEmpty) {
            Map newInfoMap = new HashMap();
            Set keySet = orderInfoMap.keySet();
            Iterator iterator = keySet.iterator();
            while (iterator.hasNext()) {
                Object key = iterator.next();
                Object value = orderInfoMap.get(key);
                if (value != null && value.toString().replaceAll("\\s*", "").length() > 0) {
                    newInfoMap.put(key, value);
                }
            }
            orderInfoMap = newInfoMap;
        }

        translateOrderPrice(orderInfoMap, TranslateType.forDatabaseSave);
        updateOrderInfoByMap(orderInfoMap);
        associateUpdateSalesOrderInfo(orderInfoMap);
    }

    /**
     * 更新生产订单信息
     *
     * @param orderInfoMap 订单更新字段集合
     */
    private void updateOrderInfoByMap(Map orderInfoMap) {
        orderInfoDao.updateOrderInfoByMap(orderInfoMap);
    }

    /**
     * 转换订单价格数据信息
     *
     * @param order         生产订单信息Map
     * @param translateType 转换类型
     */
    private void translateOrderPrice(Map order, int translateType) {
        String[] stringArray;
        double rate = 1, millionRate = 1;
        if (translateType == TranslateType.forDatabaseSave) {
            rate = 100;
            millionRate = 10000;
        } else if (translateType == TranslateType.forWebShow) {
            rate = 0.01;
            millionRate = 0.0001;
        } else {
            logger.error("error parameter value got: translateType=" + translateType);
        }

        //价格列
        stringArray = new String[]{"interest", "loanAmount", "appraisalCost", "loansAmount",
                "approveMoney", "advanceFundMoney", "installmentRepayment", "settlementAmount", "foreignRebates", "channelRebates", "loanMoney"};
        List<String> priceColList = Arrays.asList(stringArray);
        //万元价格列
        stringArray = new String[]{"loansAmount", "advanceFundMoney", "loanMoney"};
        List<String> millionPriceColList = Arrays.asList(stringArray);

        BigDecimal bd_rate = BigDecimal.valueOf(rate);
        BigDecimal bd_million_rate = BigDecimal.valueOf(millionRate);
        for (String priceColumn : priceColList) {
            if (order.get(priceColumn) != null) {
                String valStr = order.get(priceColumn).toString().trim();
                BigDecimal value = new BigDecimal(valStr);
                value = value.multiply(bd_rate).setScale(2, BigDecimal.ROUND_HALF_UP); //保留2位小数
                if (millionPriceColList.contains(priceColumn)) {
                    value = value.multiply(bd_million_rate).setScale(2, BigDecimal.ROUND_HALF_UP);
                }
                if (translateType == TranslateType.forDatabaseSave) {
                    order.put(priceColumn, value.longValue());

                } else {
                    order.put(priceColumn, value);
                }

            }
        }
    }

    /**
     * 根据主（销售）订单查询生产订单List
     *
     * @param salesOrderId 销售主订单id
     * @return
     */
    public List<Map> queryOrderListBySalesOrderId(long salesOrderId) {
        Map para = new HashMap();
        para.put("salesOrderId", salesOrderId);
        List<Map> orderList = orderInfoDao.queryOrderListByMap(para);
        generateBusiTypeMark(orderList);
        if (orderList != null && orderList.size() > 0) {

            for (Map order : orderList) {
                //订单业态编码
                order.put("statusCode", order.get("status"));
                //查询订单预计完成时间
                ScProOrderTimeState orderTimeState = repository.get(ScProOrderTimeState.class, Long.valueOf(order.get("id").toString()));
                if (orderTimeState != null) {
                    order.put("expectedFinishDate", orderTimeState.getOrderOverdueTime());
                }
                translateOrderPrice(order, TranslateType.forWebShow);
                //解密客户电话号码
                Object value = order.get("customerName");
                if (value != null && value.toString().length() > 0) {
                    order.put("customerName", njCodeUtil.decrypt(value.toString()));
                }

                trimOrderInfo(order);
                //订单流程节点信息
                generateOrderFlowList(order);
                associateQurySalesOrderInfo(order);
            }
        }
        TranslateMapUtil.translateMap(column, orderList);
        return orderList;

    }


    /**
     * @param order 订单属性map
     * @descrition 生成订单流程节点及节点信息
     * @author 赵有文
     */
    private void generateOrderFlowList(Map order) {
        Map paraMap;
        Object value;
        long orderId;
        if (order.get("id") == null) return;
        orderId = Long.parseLong(order.get("id").toString());

        String currentNode = order.get("curNode") == null ? "" : order.get("curNode").toString();
        value = order.get("nodeFlowId");
        if (value != null) {
            paraMap = new HashMap();
            paraMap.put("processid", value.toString());
            List<Map> flowNodeList = nodeManagerService.queryNodeList(paraMap);  //查询订单节点结构

            paraMap = new HashMap();
            paraMap.put("proid", orderId + "");
            List<Map> flowNodeInfoList = nodeManagerService.queryOperationinfo(paraMap);    //获取订单节点信息
            Map<String, Map> flowNodeInfoMap = new HashMap<String, Map>();
            for (Map nodeInfor : flowNodeInfoList) {
                if (nodeInfor.get("nodeName") == null) continue;
                String name = nodeInfor.get("nodeName").toString();
                if (!flowNodeInfoMap.containsKey(name)) {
                    flowNodeInfoMap.put(name, nodeInfor);
                }
            }
            int index = 1;
            for (Map node : flowNodeList) {

                if (node.get("name") == null) continue;
                String name = node.get("name").toString();
                paraMap.put("nodeid", node.get("id").toString());
                node.put("index", index++);
                if (order.get("latestnode") != null && order.get("latestnode").toString() == node.get("name").toString()) {
                    order.put("currentNodeIndex", index);
                }
                if (flowNodeInfoMap.containsKey(name)) {
                    Map latestNodeInfo = flowNodeInfoMap.get(name);
                    String latestDate = latestNodeInfo.get("createtime").toString().substring(0, 10);
                    node.put("date", latestDate.replaceAll("-", "/"));
                    node.put("status", " ");//已完成
                    Object nodeState = latestNodeInfo.get("nodeState");
                    if (nodeState != null && nodeState.toString().equals(OverdueStateConstant.TIME_OUT)) {
                        node.put("status", "over-unfinished");//超期已完成
                    }
                } else {
                    node.put("status", "unfinished");//未完成
                    value = order.get("nodeUltraTime");
                    String nodeName = node.get("name") != null ? node.get("name").toString() : "";
                    if (value != null && value.toString().equals(OverdueStateConstant.TIME_OUT) && currentNode.equals(nodeName)) {
                        node.put("status", "over");//超期
                    }
                }
            }
            order.put("flowNodeList", flowNodeList);
        }
    }

    /**
     * 查询借贷人电话号码
     * @param orderId
     * @return
     */
    public List<OrderContact> queryLenderContactList(Long orderId) {

        List<OrderContact> contacts = orderContactService.queryOrder("orderId", orderId);
        for (int i = 0; i < contacts.size(); i++) {
            OrderContact contact = contacts.get(i);
            this.repository.getSession().evict(contact);
            String phone = contact.getNo();
            if (phone != null && phone.length() > 0) {
                phone = njCodeUtil.decrypt(phone);
            }
            contact.setNo(phone);
        }

        return contacts;

    }


    /**
     * 参数常量：订单价格转换用途类型
     */
    public static class TranslateType {
        public static final int forDatabaseSave = 1;//为了数据库存储
        public static final int forWebShow = 2;//为了前台展示
    }

    /**
     * 关联查询主订单属性    表:sc_order
     *
     */
    private void associateQurySalesOrderInfo(Map orderInfo) {
        Property orderProp = new Property(orderInfo);
        String btCode = orderProp.getString("btcode");
        if (!btCode.equals("抵押贷款")) return;

        Long innerMainOrderId = orderProp.getLong("proorderid");
        if (innerMainOrderId > -1) {
            Map para = new HashMap();
            para.put("id", innerMainOrderId);
            Map mainOrderInfo = orderInfoDao.queryMainOrderInfoByMap(para);
            for (Object key : mainOrderInfo.keySet()) {
                orderInfo.put(key, mainOrderInfo.get(key));
            }
        }
    }

    /**
     * 联动更新主订单属性  表：sc_order
     *
     * @param orderInfo
     */
    private void associateUpdateSalesOrderInfo(Map orderInfo) {
        String[] array = new String[]{"mortgageAddress"};
        List<String> colList = Arrays.asList(array);

        for (String col : colList) {
            if (orderInfo.containsKey(col)) {
                orderInfoDao.updateMainOrderInfoByMap(orderInfo);
                break;
            }
        }
    }

    public void trimOrderInfoList(List<Map> orderList){

        for(Map order:orderList){

            trimOrderInfo(order);
        }

    }


    private void trimOrderInfo(Map order){
        Object value;
        Map<String,String> payBackWayTypes;
    //还款方式
        order.put("payBackWay",null);
        value=order.get("wayofloan");
        if(value!=null){
            payBackWayTypes=new HashMap();
            payBackWayTypes.put("1","分期还款");
            payBackWayTypes.put("2","其他");
            payBackWayTypes.put("3","先息后本");
            payBackWayTypes.put("4","等额等息");
            payBackWayTypes.put("5","等额本金");
            payBackWayTypes.put("6","等本等息");
            payBackWayTypes.put("7","减本减息");
            payBackWayTypes.put("8","计划归本");
            String payBackWayCode=value.toString();
            if(payBackWayTypes.containsKey(payBackWayCode)){

             String   payBackWay=payBackWayTypes.get(payBackWayCode);
                value =order.get("dateofloan");
                if(value!=null){
                  String  payBackDate=value.toString();
                    payBackDate="128".contains(payBackWayCode)?payBackDate:"每月"+payBackDate+"号";
                    payBackWay+=" "+payBackDate;
                }
                order.put("payBackWay",payBackWay);
            }


        }



    }
}

